package com.cskaoyan.javase.oop1._17access._3why;

import java.util.Arrays;

/**
 * 访问权限修饰符的作用,为什么使用访问权限修饰符?
 * 给类或者类中结构加上访问权限，就相当于给房子加锁，没有钥匙（没有访问权限）就进不去（访问不到）
 * 但以上说的是正常情况
 * 房子的锁是可以撬开，是可以强行打破的，同样的访问权限符也不是绝对不可破解的。
 * 比如Java自身就提供了反射的特性，反射是可以破解访问权限的。
 *
 * 那么就像给门加锁，是警告你不能逾越界限，否则就是违法操作一样。
 * 访问权限的使用，最基本的，自然是用来控制访问权限的（这是废话）。
 * 但也隐含了警告和暗示的作用：
 *      告诉代码的使用者，哪些地方不要触碰，哪些地方应该使用。
 *      起到警告、约束和指导代码使用者的功能。
 *
 * 具体来说:
 * 1.就是专门提供给外界使用的,推荐外界使用的地方，用public修饰。
 *      用public修饰就是告诉别人,这里应该被使用
 * 2.不应该触碰的地方，用私有private修饰，
 *      告诉别人：这里你不需要你看，也不需要你管。你不要查看,更不要使用
 *
 * 具体案例:
 *      1.专门提供给外界使用的方法应该用public修饰
 *          同时在实现这些提供给外部使用的方法过程中,出现的中间的,过程方法
 *          这些过程方法不需要给外界使用,那应该private修饰它,应该私有化
 *
 *          强调: 开发中会写很多中间过程方法,它们都应该私有化,不要随意使用public修饰它们.
 *
 *      2.工具类,当中都是static方法,使用工具类,直接类名点就可以了
 *          完全不需要创建它的对象
 *          于是既然不需要对象,那就干脆不要创建对象了
 *          于是私有化构造器
 *          所有工具类,都应该主动私有化它的构造器,避免在外界创建对象
 *
 *      3.工厂设计模式,以及单例的设计模式
 *          工厂设计模式指的是创建对象不依赖于自身类,而是依赖于一个"工厂类"来"生产"它的对象
 *          单例的设计模式指的是在整个JVM全局,这个类的对象只有一个,称之为"单例"
 *          它们的类都不能依赖于自身构造器创建对象, 它们都需要私有化自身类的构造器,避免在外界直接创建对象
 *
 * 思考：上述这些做法有何好处？
 * 如果你能够严格按照上述描述使用访问权限修饰符，那么好处是显而易见的：
 * 把代码的开发者和代码的使用者给区分开来了：
 * 对代码使用者的好处:
 * 代码使用者无需关心没有访问权限的代码，仅需要关心具有访问权限的部分就可以了。
 * 私有或者没有访问权限的部分，既然不让我看，不让我用，那我就老老实实不看，不用。
 * 实际上，当你去使用别人的代码时，你也不希望需要完全读懂所有代码，才能够使用吧？
 *
 * 对代码开发者的好处:
 * 代码开发者，可以自由的开发，对外界没有访问权限部分的代码。
 * 这些私有的，或者对外界不可见部分的代码，叫做隐藏代码的具体实现细节，可以很方便的修改代码实现。
 * 想一想，如果一个方法是public修饰的，在外界多处被使用，你敢随便就动这个方法代码吗？
 *
 * 所以总结一下使用访问权限修饰符的原则,给一个结构访问权限的原则:
 *      1.尽量私有化，方便自己修改代码，隐藏实现细节。而且确实不需要给外界看的,私有化它,也能够节省代码使用者的时间
 *      2.如果不能私有化，那也应该尽量少的给予访问权限，先从默认权限开始考虑。
 *      3.只有确定这个结构，一定需要在外部（尤其是不同包下）被访问时，才考虑给public，尽量少给public。
 * 权限这个东西，要吝啬，不要"大方"！
 *
 * @since 10:51
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        s.getScore();;

        // new Arrays();
    }
}

class Student {
    double score;

    /*
        查看学生成绩的方法
     */
    public void getScore() {
        test();
        System.out.println("成绩是" + score);
    }

    public void getScore2() {
        test();
        System.out.println("成绩是" + score);
    }

    private void test() {
        System.out.println("这是查看成绩的中间操作~~~");
    }

}